package com.paishen.common.dialog.picker;

import android.app.Dialog;
import android.content.Context;
import android.text.TextUtils;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.TextView;

import com.paishen.common.R;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.List;

public class PnwDateDateTimePickerDialog extends Dialog {

    private Params params;

    public interface OnPnwDateDateTimeSelectedListener {
        void onPnwDateDateTimeSelected(String dateDateValues);
    }

    public PnwDateDateTimePickerDialog(Context context, int themeResId) {
        super(context, themeResId);
    }

    private void setParams(PnwDateDateTimePickerDialog.Params params) {
        this.params = params;
    }

    private static final class Params {
        boolean isTomorrow = false;
        private String[] specialDaysOfWeek;
        private String[] daysValue;
        private String title;
        private LoopView loopDay, loopHour, loopMin;
        private OnPnwDateDateTimeSelectedListener callback;
        private Context context;
    }

    public static class Builder {
        private Params p;
        private boolean shadow = true;
        private boolean canCancel = true;
        private final int OFFSET = 30;
        private final int MIN_SPACING = 5;

        public Builder(Context context) {
            p = new Params();
            p.context = context;
            p.daysValue = p.context.getResources().getStringArray(R.array.pnw_date_time_range);
            p.specialDaysOfWeek = p.context.getResources().getStringArray(R.array.pnw_date_date_time_special_days_of_week);
        }

        public Builder setTitle(String title) {
            p.title = title;
            return this;
        }

        private void resetOptionalDaysValue() {
            int fixPosition = p.loopDay.getCurrentItem();
            if (fixPosition > 0) fixPosition -= 1;

            if (p.isTomorrow) {
                Calendar c = Calendar.getInstance();
                int month = c.get(Calendar.MONTH) + 1;
                String mMonth = (month > 10 ? "" : "0") + month;
                int dayOfMonth = c.get(Calendar.DAY_OF_MONTH);
                String mDayOfMonth = (dayOfMonth > 10 ? "" : "0") + dayOfMonth;
                int dayOfWeek = c.get(Calendar.DAY_OF_WEEK);
                String specialDaysOfWeekInfo = p.context.getString(R.string.pnw_date_date_time_special_days, mMonth, mDayOfMonth)
                        + " " + p.specialDaysOfWeek[dayOfWeek];

                List<String> days = new ArrayList<>();
                days.add(p.daysValue[1]);
                days.add(p.daysValue[2]);
                days.add(specialDaysOfWeekInfo);
                p.loopDay.setArrayList(days);
            } else {
                p.loopDay.setArrayList(Arrays.asList(p.daysValue));
            }
            p.loopDay.setCurrentItem(fixPosition);
        }

        private void resetOptionalHourValue() {
            Calendar c = Calendar.getInstance();
            int mHour = c.get(Calendar.HOUR_OF_DAY);
            int mMin = c.get(Calendar.MINUTE) + OFFSET;

            if (mMin > 60 - MIN_SPACING) {
                mHour += 1;
                mMin = (mMin > 60) ? mMin % 60 : 0;
            }
            if (mHour >= 24) {
                if (p.isTomorrow == false) {
                    p.isTomorrow = true;
                    resetOptionalDaysValue();
                    return;
                }
                mHour = mHour % 24;
            } else {
                if (p.isTomorrow == true) {
                    p.isTomorrow = false;
                    resetOptionalDaysValue();
                    return;
                }
            }

            int fixPosition = p.loopHour.getCurrentItem();
            if (p.loopDay.getCurrentItem() == 0) {
                p.loopHour.setArrayList(d(mHour, 24 - mHour));
            } else if (p.loopDay.getCurrentItem() == p.loopDay.valueSize() - 1) {
                p.loopHour.setArrayList(d(0, mHour + 1));
            } else {
                p.loopHour.setArrayList(d(0, 24));
            }
            if (fixPosition >= p.loopHour.valueSize()) fixPosition = p.loopHour.valueSize() - 1;
            p.loopHour.setCurrentItem(fixPosition);
        }

        private void resetOptionalMinValue() {
            Calendar c = Calendar.getInstance();
            int mHour = c.get(Calendar.HOUR_OF_DAY);
            int mMin = c.get(Calendar.MINUTE) + OFFSET;

            if (mMin > 60 - MIN_SPACING) {
                mHour += 1;
                mMin = (mMin > 60) ? mMin % 60 : 0;
            }
            if (mHour >= 24) {
                if (p.isTomorrow == false) {
                    p.isTomorrow = true;
                    resetOptionalDaysValue();
                    return;
                }
                mHour = mHour % 24;
            } else {
                if (p.isTomorrow == true) {
                    p.isTomorrow = false;
                    resetOptionalDaysValue();
                    return;
                }
            }

            int fixPosition = p.loopMin.getCurrentItem();
            if (p.loopDay.getCurrentItem() == 0 && p.loopHour.getCurrentItem() == 0) {
                p.loopMin.setArrayList(d(mMin, 60 - mMin, MIN_SPACING));
            } else if (p.loopDay.getCurrentItem() == p.loopDay.valueSize() - 1
                    && p.loopHour.getCurrentItem() == p.loopHour.valueSize() - 1) {
                p.loopMin.setArrayList(d(0, mMin + MIN_SPACING, MIN_SPACING));
            } else {
                p.loopMin.setArrayList(d(0, 60, MIN_SPACING));
            }
            if (fixPosition >= p.loopMin.valueSize()) fixPosition = p.loopMin.valueSize() - 1;
            p.loopMin.setCurrentItem(fixPosition);
        }

        public Builder setOnPnwEventDateTimeSelectedListener(OnPnwDateDateTimeSelectedListener onPnwEventDateTimeSelectedListener) {
            p.callback = onPnwEventDateTimeSelectedListener;
            return this;
        }

        public PnwDateDateTimePickerDialog create() {
            final PnwDateDateTimePickerDialog dialog = new PnwDateDateTimePickerDialog(p.context, shadow ? R.style.Theme_Light_NoTitle_Dialog : R.style.Theme_Light_NoTitle_NoShadow_Dialog);
            View view = LayoutInflater.from(p.context).inflate(R.layout.layout_picker_pnw_date_datetime, null);
            p.loopDay = (LoopView) view.findViewById(R.id.loop_day);
            p.loopDay.setNotLoop();
            p.loopHour = (LoopView) view.findViewById(R.id.loop_hour);
            p.loopHour.setNotLoop();
            p.loopMin = (LoopView) view.findViewById(R.id.loop_min);
            p.loopMin.setNotLoop();

            resetOptionalDaysValue();
            resetOptionalHourValue();
            resetOptionalMinValue();

            p.loopDay.setListener(new LoopListener() {
                @Override
                public void onItemSelect(int item) {
                    resetOptionalHourValue();
                    resetOptionalMinValue();
                }
            });

            p.loopHour.setListener(new LoopListener() {
                @Override
                public void onItemSelect(int item) {
                    resetOptionalMinValue();
                }
            });

            TextView txTitle = (TextView) view.findViewById(R.id.tx_title);
            if (!TextUtils.isEmpty(p.title)) {
                txTitle.setText(p.title);
            }

            view.findViewById(R.id.tx_finish).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    dialog.dismiss();

                    Calendar c = Calendar.getInstance();
                    long timestamp = c.getTimeInMillis();
                    timestamp = timestamp + 86400000 * (p.loopDay.getCurrentItem() + (p.isTomorrow ? 1 : 0));
                    c.setTimeInMillis(timestamp);
                    String result = c.get(Calendar.YEAR) + "-" + (c.get(Calendar.MONTH) + 1) + "-" + c.get(Calendar.DATE) + " "
                            + p.loopHour.getCurrentItemValue() + ":" + p.loopMin.getCurrentItemValue();
                    p.callback.onPnwDateDateTimeSelected(result);
                }
            });

            Window win = dialog.getWindow();
            win.getDecorView().setPadding(0, 0, 0, 0);
            WindowManager.LayoutParams lp = win.getAttributes();
            lp.width = WindowManager.LayoutParams.MATCH_PARENT;
            lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
            win.setAttributes(lp);
            win.setGravity(Gravity.BOTTOM);
            win.setWindowAnimations(R.style.Animation_Bottom_Rising);

            dialog.setContentView(view);
            dialog.setCanceledOnTouchOutside(canCancel);
            dialog.setCancelable(canCancel);
            dialog.setParams(p);
            return dialog;
        }

        /**
         * 将数字传化为集合，并且补充0
         *
         * @param startNum 数字起点
         * @param count    数字个数
         * @return
         */
        private List<String> d(int startNum, int count) {
            String[] values = new String[count];
            for (int i = startNum; i < startNum + count; i++) {
                String tempValue = (i < 10 ? "0" : "") + i;
                values[i - startNum] = tempValue;
            }
            return Arrays.asList(values);
        }

        private List<String> d(int startNum, int count, int l) {
            ArrayList<String> values = new ArrayList();
            for (int i = startNum; i < startNum + count; i++) {
                if (i % l != 0) continue;
                String tempValue = (i < 10 ? "0" : "") + i;
                values.add(tempValue);
            }
            return values;
        }
    }
}
